﻿/*******************************************************
* Copyright (c) 2018-2088, By XuXiang all rights reserved.
*
* FileName: FightFrameRecord.cpp
* Summary: 战斗帧记录。
*
* Author: XuXiang
* Date: 2024-06-06 22:46
*******************************************************/

#include "FightFrameRecord.h"
#include <Protocol/NetMsgFight.h>
using namespace Competition::Net;

namespace Competition
{
	FightFrameIndex::FightFrameIndex()
	{
	}

	FightFrameIndex::FightFrameIndex(int c, int i):chunk(c), index(i)
	{
	}

	int FightFrameRecord::ChunkSize = 1024 * 1024 * 8;

	FightFrameRecord::FightFrameRecord()
	{
		m_Chunks.push_back(new Byte[ChunkSize]);
		m_Frames.reserve(20 * 60 * 10);		//一秒钟20帧，初始分配10分钟
	}

	FightFrameRecord::~FightFrameRecord()
	{
		for (auto itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) 
		{
			SAFE_DELETE_ARRAY(*itr);
		}
		m_Chunks.clear();
		m_Frames.clear();

	}

	void FightFrameRecord::AddFrame(Net::SCFightOperateFrameNotify& ntf)
	{
		//当前区块已经不够写入了
		if ((m_WriteIndex + ntf.Size) > ChunkSize)
		{
			m_WriteIndex = 0;
			m_Chunks.push_back(new Byte[ChunkSize]);
		}

		//写入帧数据
		FightFrameIndex fi((int)m_Chunks.size() - 1, m_WriteIndex);
		Byte* chunk = m_Chunks[fi.chunk];
		m_Frames.push_back(fi);
		m_WriteIndex = ntf.Pack(chunk, m_WriteIndex);
	}

	int FightFrameRecord::TakeRecord(int start, int end, bool last, Net::SCFightFrameRecordResponse& res)
	{
		int to = min(end, (int)m_Frames.size());
		int max_n = NET_PACKAGE_MAX_SIZE - 4 - 1;		//4字节为最终长度，1字节为结束标记
		int frame_count = 0;
		int write_index = 0;
		int count_write_index = write_index;
		write_index = DataUtil::WriteInt32(res.Bytes, write_index, frame_count);
		for (int i = start; i < to; ++i)
		{
			FightFrameIndex fi = m_Frames[i];
			Byte* chunk = m_Chunks[fi.chunk];
			int read_index = fi.index;
			int size = DataUtil::ReadInt32(chunk, read_index, &read_index);
			if (write_index + size >= max_n)
			{
				//已经不能再写入了
				break;
			}
			DataUtil::ReadBytes(chunk, read_index, size, res.Bytes, write_index, &write_index);
			++frame_count;
		}
		DataUtil::WriteInt32(res.Bytes, count_write_index, frame_count);		//重新写入数量
		int next_frame = start + frame_count;
		write_index = DataUtil::WriteByte(res.Bytes, write_index, last || next_frame >= end ? 1 : 0);
		res.Size = write_index;
		return next_frame;
	}
}

